﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
//using T.FAS.Authority.MetaData.Entity;
using T.FAS.Runtime.Metadata.Entity.Page;

namespace T.FAS.Runtime.Page.Dao
{
    public class PageMetaDataLogic
    {
        readonly PageExtPropertyDao pageExtPropertyDao = new PageExtPropertyDao();
        readonly PageCacheDao pageCacheDao = new PageCacheDao();
        readonly PageEntryDao pageEntryDao = new PageEntryDao();

        readonly PageMetaDataDao pageMetaDataDao = new PageMetaDataDao();
        readonly PageVariableDao pageVariableDao = new PageVariableDao();
        readonly PageViewModelDao pageViewModelDao = new PageViewModelDao();
        readonly PageActionParameterDao pageActionParameterDao = new PageActionParameterDao();
        readonly PageEventDao pageEventDao = new PageEventDao();
        readonly PageCtrlEventDao pageCtrlEventDao = new PageCtrlEventDao();
        readonly PageHeaderDao pageHeaderDao = new PageHeaderDao();
        readonly StyleSheetDao styleSheetDao = new StyleSheetDao();
        readonly PageUIControlDao pageUIControlDao = new PageUIControlDao();
        readonly PageCSSDao pageCSSDao = new PageCSSDao();
        readonly PageMethodDao pageMethodDao = new PageMethodDao();
        readonly PageStateMachineDao pageStateMachineDao = new PageStateMachineDao();

        readonly PageUIControlLogic pageUIControlLogic = new PageUIControlLogic();
        /// <summary>
        /// 新增
        /// </summary>
        /// <param name="pageMetaData"></param>
        public void AddPageMetaData(PageMetaData pageMetaData)
        {
            List<PageActionParameter> pageActionParameters = new List<PageActionParameter>();
            int order = 0;
            foreach (var item in pageMetaData.PageParameters)
            {
                item.ID = Guid.NewGuid().ToString();
                item.PageID = pageMetaData.ID;
                item.VariableOrder = order++;
                item.VariableType = VariableType.InParameter;
            }
            pageVariableDao.Add(pageMetaData.PageParameters);
            foreach (var item in pageMetaData.PageOutParameters)
            {
                item.ID = Guid.NewGuid().ToString();
                item.PageID = pageMetaData.ID;
                item.VariableOrder = order++;
                item.VariableType = VariableType.OutParameter;
            }
            pageVariableDao.Add(pageMetaData.PageOutParameters);
            foreach (var item in pageMetaData.LocalVariables)
            {
                item.ID = Guid.NewGuid().ToString();
                item.PageID = pageMetaData.ID;
                item.VariableOrder = order++;
                item.VariableType = VariableType.Variable;
            }
            pageVariableDao.Add(pageMetaData.LocalVariables);
            order = 0;
            foreach (var item in pageMetaData.ViewModels)
            {
                item.ID = Guid.NewGuid().ToString();
                item.PageID = pageMetaData.ID;
                item.ViewModelOrder = order++;
                int j = 0;
                foreach (var item2 in item.Parameters)
                {
                    item2.ID = Guid.NewGuid().ToString();
                    item2.PageID = pageMetaData.ID;
                    item2.ParameterOrder = j++;
                    item2.EventID = item.ID;
                    pageActionParameters.Add(item2);
                }
            }
            pageViewModelDao.Add(pageMetaData.ViewModels);
            if (pageMetaData.Header != null)
            {
                PageHeader pageHeader = pageMetaData.Header;
                pageHeader.ID = pageMetaData.ID;
                if (pageHeader.StyleSheet != null)
                {
                    StyleSheet styleSheet = pageHeader.StyleSheet;
                    styleSheet.ID = pageMetaData.ID;
                    styleSheetDao.Add(new List<object> { styleSheet });
                }
                if (pageHeader.Style != null)
                {
                    PageCSS pageCSS = pageHeader.Style;
                    if (pageCSS.ClassList != null && pageCSS.ClassList.Count > 0)
                        pageCSS.CustomClass = string.Join(",", pageCSS.ClassList);
                    pageCSS.ID = pageMetaData.ID;
                    pageCSS.PageID = pageMetaData.ID;
                    pageCSSDao.Add(new List<object> { pageCSS });
                }
                if (pageHeader.CacheConfig != null)
                {
                    PageCache pageCache = pageHeader.CacheConfig;
                    pageCache.ID = pageMetaData.ID;
                    pageCacheDao.Add(new List<object> { pageCache });
                }
                /* Todo
                if (pageHeader.BPO != null)
                    pageHeader.BPOID = pageHeader.BPO.Id;
                */
                if (pageHeader.Theme != null)
                    pageHeader.ThemeID = pageHeader.Theme.ID;
                foreach (var item in pageHeader.PageStateMachines)
                {
                    item.ID = Guid.NewGuid().ToString();
                    item.PageID = pageMetaData.ID;
                }
                pageStateMachineDao.Add(pageHeader.PageStateMachines);
                pageHeaderDao.Add(new List<object> { pageHeader });
            }
            List<PageExtProperty> pageExtProperties = new List<PageExtProperty>();
            order = 0;
            foreach (var item in pageMetaData.ExtProperties)
            {
                item.Value.Code = item.Key;
                item.Value.PageID = pageMetaData.ID;
                item.Value.ID = Guid.NewGuid().ToString();
                item.Value.PropertyOrder = order++;
                pageExtProperties.Add(item.Value);
            }
            pageExtPropertyDao.Add(pageExtProperties);
            order = 0;
            foreach (var item in pageMetaData.Events)
            {
                item.ID = Guid.NewGuid().ToString();
                item.PageID = pageMetaData.ID;
                item.EventOrder = order++;
            }
            pageEventDao.Add(pageMetaData.Events);
            foreach (var item in pageMetaData.CtrlEvents)
            {
                item.ID = Guid.NewGuid().ToString();
                item.PageID = pageMetaData.ID;
                item.EventOrder = order++;
                int j = 0;
                foreach (var item2 in item.Parameters)
                {
                    item2.ID = Guid.NewGuid().ToString();
                    item2.PageID = pageMetaData.ID;
                    item2.ParameterOrder = j++;
                    item2.EventID = item.ID;
                    pageActionParameters.Add(item2);
                }
            }
            pageCtrlEventDao.Add(pageMetaData.CtrlEvents);
            foreach (var item in pageMetaData.CtrlMethods)
            {
                item.ID = Guid.NewGuid().ToString();
                item.PageID = pageMetaData.ID;
                item.MethodOrder = order++;
                int j = 0;
                foreach (var item2 in item.Parameters)
                {
                    item2.ID = Guid.NewGuid().ToString();
                    item2.PageID = pageMetaData.ID;
                    item2.ParameterOrder = j++;
                    item2.EventID = item.ID;
                    pageActionParameters.Add(item2);
                }
            }
            pageMethodDao.Add(pageMetaData.CtrlMethods);
            pageActionParameterDao.Add(pageActionParameters);
            order = 0;
            foreach (var item in pageMetaData.PCUIDom.Controls)
            {
                item.ID = Guid.NewGuid().ToString();
                item.PageID = pageMetaData.ID;
                item.ParentID = pageMetaData.ID;
                item.DomType = DomType.PCUIDom;
                item.ControlOrder = order++;
            }
            pageUIControlLogic.AddPageUIControls(pageMetaData.PCUIDom.Controls);
            if (pageMetaData.PageEntry != null)
            {
                pageMetaData.PageEntry.ID = pageMetaData.ID;
                pageEntryDao.Add(new List<object> { pageMetaData.PageEntry });
            }
            pageMetaDataDao.Add(new List<object> { pageMetaData });
        }
        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="ID"></param>
        public void DeletePageMetaData(string ID)
        {
            pageMetaDataDao.Delete(new List<string> { ID });
            pageActionParameterDao.Delete(new List<string> { ID });
            pageCacheDao.Delete(new List<string> { ID });
            pageCSSDao.Delete(new List<string> { ID });
            pageEntryDao.Delete(new List<string> { ID });
            pageEventDao.Delete(new List<string> { ID });
            pageExtPropertyDao.Delete(new List<string> { ID });
            pageCtrlEventDao.Delete(new List<string> { ID });
            pageHeaderDao.Delete(new List<string> { ID });
            styleSheetDao.Delete(new List<string> { ID });
            pageUIControlDao.Delete(new List<string> { ID });
            pageVariableDao.Delete(new List<string> { ID });
            pageViewModelDao.Delete(new List<string> { ID });
            pageStateMachineDao.Delete(new List<string> { ID });
            pageMethodDao.Delete(new List<string> { ID });
            pageExtPropertyDao.Delete(new List<string> { ID });
        }

        /// <summary>
        /// 根据ID查询
        /// </summary>
        /// <param name="ID"></param>
        /// <returns></returns>
        public PageMetaData GetPageMetaData(string ID)
        {
            PageMetaData pageMetaData = pageMetaDataDao.GetObject(ID);
            if (pageMetaData != null)
            {
                List<PageExtProperty> pageExtProperties = pageExtPropertyDao.GetPageExtPropertys(ID).OrderBy(t => t.PropertyOrder).ToList();
                Dictionary<string, PageExtProperty> dic = new Dictionary<string, PageExtProperty>();
                foreach (var item in pageExtProperties)
                {
                    dic[item.Code] = item;
                }
                pageMetaData.ExtProperties = dic; 
                List<PageActionParameter> pageActionParameters = pageActionParameterDao.GetPageActionParameters(ID);
                List<PageCSS> pageCSSs = pageCSSDao.GetPageCSSs(ID);
                List<PageUIControl> pageUIControls = pageUIControlDao.GetPageUIControls(ID);
                List<PageVariable> pageVariables = pageVariableDao.GetPageVariables(ID);
                pageMetaData.Header = pageHeaderDao.GetObject(ID);
                pageMetaData.PageParameters = pageVariables.Where(t => t.VariableType == VariableType.InParameter).OrderBy(t => t.VariableOrder).ToList();
                pageMetaData.PageOutParameters = pageVariables.Where(t => t.VariableType == VariableType.OutParameter).OrderBy(t => t.VariableOrder).ToList();
                pageMetaData.LocalVariables = pageVariables.Where(t => t.VariableType == VariableType.Variable).OrderBy(t => t.VariableOrder).ToList();
                pageMetaData.Events = pageEventDao.GetPageEvents(ID).OrderBy(t=>t.InstanceCode).ThenBy(t=>t.EventOrder).ToList();
                if (pageMetaData.Header != null)
                {
                    pageMetaData.Header.Style = pageCSSs.FirstOrDefault(t => t.ID == ID);
                    if (pageMetaData.Header.Style != null)
                    {
                        if (!string.IsNullOrEmpty(pageMetaData.Header.Style.CustomClass))
                            pageMetaData.Header.Style.ClassList = pageMetaData.Header.Style.CustomClass.Split(',').ToList();
                        else
                            pageMetaData.Header.Style.ClassList = new List<string>();
                    }
                    else
                        pageMetaData.Header.Style = new PageCSS();
                    pageMetaData.Header.StyleSheet = styleSheetDao.GetObject(ID);
                    if (pageMetaData.Header.StyleSheet == null)
                        pageMetaData.Header.StyleSheet = new StyleSheet();
                    pageMetaData.Header.Theme = new ThemeMetaData { ID = pageMetaData.Header.ThemeID };
                    List<PageStateMachine> stateMachines = new PageStateMachineDao().GetPageStateMachines(ID);
                    pageMetaData.Header.PageStateMachines = stateMachines;
                    pageMetaData.Header.CacheConfig = pageCacheDao.GetObject(ID);
                    if (pageMetaData.Header.CacheConfig == null)
                        pageMetaData.Header.CacheConfig = new PageCache();
                }
                else
                {
                    pageMetaData.Header = new PageHeader();
                }
                pageMetaData.CtrlMethods = pageMethodDao.GetPageMethod(ID).OrderBy(t => t.MethodOrder).ToList();
                foreach (var item in pageMetaData.CtrlMethods)
                {
                    item.Parameters = pageActionParameters.Where(t => t.EventID == item.ID).OrderBy(t => t.ParameterOrder).ToList();
                }
                pageMetaData.CtrlEvents = pageCtrlEventDao.GetPageCtrlEvents(ID).OrderBy(t => t.EventOrder).ToList();
                foreach (var item in pageMetaData.CtrlEvents)
                {
                    item.Parameters = pageActionParameters.Where(t => t.EventID == item.ID).OrderBy(t => t.ParameterOrder).ToList();
                }
                pageMetaData.PageEntry = pageEntryDao.GetObject(ID);
                if (pageMetaData.PageEntry != null)
                    pageMetaData.PageEntry = new PageEntry();
                pageMetaData.ViewModels = pageViewModelDao.GetPageViewModels(ID).OrderBy(t => t.ViewModelOrder).ToList();
                foreach (var item in pageMetaData.ViewModels)
                {
                    item.Parameters = pageActionParameters.Where(t => t.EventID == item.ID).OrderBy(t => t.ParameterOrder).ToList();
                }
                List<PageUIControl> PCUIDom = new PageUIControlLogic().GetPageUIControls(ID, pageUIControls, pageCSSs);
                pageMetaData.PCUIDom = new PageUIDom { Controls = PCUIDom };
            }
            return pageMetaData;
        }
        /// <summary>
        /// 根据ID查询
        /// </summary>
        /// <param name="ID"></param>
        /// <returns></returns>
        public PageMetaData GetPageRTPMetaData(string ID)
        {
            PageMetaData pageMetaData = pageMetaDataDao.GetObject(ID);
            if (pageMetaData != null)
            {
                List<PageExtProperty> pageExtProperties = pageExtPropertyDao.GetPageExtPropertys(ID).OrderBy(t => t.PropertyOrder).ToList();
                Dictionary<string, PageExtProperty> dic = new Dictionary<string, PageExtProperty>();
                foreach (var item in pageExtProperties)
                {
                    dic[item.Code] = item;
                }
                pageMetaData.ExtProperties = dic;
                List<PageActionParameter> pageActionParameters = pageActionParameterDao.GetPageActionParameters(ID);
                List<PageCSS> pageCSSs = pageCSSDao.GetPageCSSs(ID);
                List<PageUIControl> pageUIControls = pageUIControlDao.GetPageUIControls(ID);
                List<PageVariable> pageVariables = pageVariableDao.GetPageVariables(ID);
                List<PageEvent> pageEvents = pageEventDao.GetPageEvents(ID);
                pageMetaData.Header = pageHeaderDao.GetObject(ID);
                pageMetaData.PageParameters = pageVariables.Where(t => t.VariableType == VariableType.InParameter).OrderBy(t => t.VariableOrder).ToList();
                pageMetaData.PageOutParameters = pageVariables.Where(t => t.VariableType == VariableType.OutParameter).OrderBy(t => t.VariableOrder).ToList();
                pageMetaData.LocalVariables = pageVariables.Where(t => t.VariableType == VariableType.Variable).OrderBy(t => t.VariableOrder).ToList();
                pageMetaData.Events = pageEvents.Where(t => t.InstanceCode == "Page" || t.InstanceCode.StartsWith("Portlet_")).OrderBy(t => t.EventOrder).ToList();
                if (pageMetaData.Header != null)
                {
                    pageMetaData.Header.Style = pageCSSs.FirstOrDefault(t => t.ID == ID);
                    if (pageMetaData.Header.Style != null)
                    {
                        if (!string.IsNullOrEmpty(pageMetaData.Header.Style.CustomClass))
                            pageMetaData.Header.Style.ClassList = pageMetaData.Header.Style.CustomClass.Split(',').ToList();
                        else
                            pageMetaData.Header.Style.ClassList = new List<string>();
                    }
                    else
                        pageMetaData.Header.Style = new PageCSS();
                    pageMetaData.Header.StyleSheet = styleSheetDao.GetObject(ID);
                    if (pageMetaData.Header.StyleSheet == null)
                        pageMetaData.Header.StyleSheet = new StyleSheet();
                    /* Todo
                    if (pageMetaData.Header.BPO == null)
                        pageMetaData.Header.BPO = new BizPermissionObject();
                    */
                    pageMetaData.Header.Theme = new ThemeMetaData { ID = pageMetaData.Header.ThemeID };
                    List<PageStateMachine> stateMachines = new PageStateMachineDao().GetPageStateMachines(ID);
                    pageMetaData.Header.PageStateMachines = stateMachines;
                    pageMetaData.Header.CacheConfig = pageCacheDao.GetObject(ID);
                    if (pageMetaData.Header.CacheConfig == null)
                        pageMetaData.Header.CacheConfig = new PageCache();
                }
                else
                    pageMetaData.Header = new PageHeader();
                pageMetaData.CtrlMethods = pageMethodDao.GetPageMethod(ID).OrderBy(t => t.MethodOrder).ToList();
                foreach (var item in pageMetaData.CtrlMethods)
                {
                    item.Parameters = pageActionParameters.Where(t => t.EventID == item.ID).OrderBy(t => t.ParameterOrder).ToList();
                }
                pageMetaData.CtrlEvents = pageCtrlEventDao.GetPageCtrlEvents(ID).OrderBy(t => t.EventOrder).ToList();
                foreach (var item in pageMetaData.CtrlEvents)
                {
                    item.Parameters = pageActionParameters.Where(t => t.EventID == item.ID).OrderBy(t => t.ParameterOrder).ToList();
                }
                pageMetaData.PageEntry = pageEntryDao.GetObject(ID);
                if (pageMetaData.PageEntry != null)
                    pageMetaData.PageEntry = new PageEntry();
                pageMetaData.ViewModels = pageViewModelDao.GetPageViewModels(ID).OrderBy(t => t.ViewModelOrder).ToList();
                foreach (var item in pageMetaData.ViewModels)
                {
                    item.Parameters = pageActionParameters.Where(t => t.EventID == item.ID).OrderBy(t => t.ParameterOrder).ToList();
                }
                List<PageUIControl> PCUIDom = new PageUIControlLogic().GetRTPPageUIControls(ID, pageUIControls, pageEvents, pageCSSs);
                pageMetaData.PCUIDom = new PageUIDom { Controls = PCUIDom };
            }
            return pageMetaData;
        }
        /// <summary>
        /// 校验唯一性
        /// </summary>
        /// <param name="ID"></param>
        public bool CheckUnique(string ID,string Code)
        {
            return pageMetaDataDao.CheckUnique(ID, Code);
        }
    }
}
